#ifndef _string_handler_h_
#define _string_handler_h_

// Quick n dirty string replace function (Not in String class)
//============================================================================================================================
String Replace(const String& s1, const String& find, const String replace) {
	String string_result;
	
	int start_pos = 0;
	int found_pos = 0;
	int find_len = find.GetCount();
	int s1_count = s1.GetCount();
	
	while(((found_pos=s1.Find(find, start_pos))!=-1)){
		string_result.Cat(s1.Mid(start_pos, found_pos - start_pos));
		string_result.Cat(replace);
		start_pos = found_pos + find_len;
	};
		
	if(start_pos<s1.GetCount())
		string_result.Cat(s1.Mid(start_pos));
		
	return (string_result);
}

// Version from Path.cpp except doesn't separate on space
//============================================================================================================================
bool PatternMatchMultiNoSpace(const char *p, const char *s) {
	String pt;
	while(*p) {
		if(*p == ';' || *p == ',') {
			if(PatternMatch(pt, s)) return true;
			p++;
			while(*p == ';' || *p == ',') p++;
			pt.Clear();
		}
		else
			pt.Cat(*p++);
	}
	return pt.IsEmpty() ? false : PatternMatch(pt, s);
}

//============================================================================================================================
bool IsUpper(const String &s) {
	for (int i=0; i < s.GetCount(); i++) {
		if (isalpha(s[i])) {
			if (!isupper(s[i])) {
				return false;
			}
		}
	}
	
	return true;
}

//============================================================================================================================
void ToUpper(String &s) {
	for (int i=0; i < s.GetCount(); i++) {
		if (isalpha(s[i])) {
			s.Set(i, toupper(s[i]));
		}
	}
}

//============================================================================================================================
void ToLower(String &s) {
	for (int i=0; i < s.GetCount(); i++) {
		if (isalpha(s[i])) {
			s.Set(i, tolower(s[i]));
		}
	}
}

//============================================================================================================================
String ToHex(const String &s) {
	String h;
	for (int i=0; i < s.GetCount(); i++) {
		h.Cat(Format("%02X", s[i]));
	}
	
	return h;
}

//============================================================================================================================
String ToHex(uint32 i) {
	return Format("%02X%02X%02X%02X", ((byte *)&i)[3], ((byte *)&i)[2], ((byte *)&i)[1], ((byte *)&i)[0]);
}

//============================================================================================================================
//  Convert integer to a string of 1's and 0's, for deciphering bit settings.
//  Gives us at least 8 bits of zeroes if a zero sent.  All inputs are split into 8-bit lists.
//============================================================================================================================
String dec2bin(long i) {
	String binstr;
	while (1) {
		for (int j=0;j < 8;j++) {
			/* bitwise AND operation with the last bit */
			binstr.Insert(0, (i & 0x1) ? "1" : "0");
			/* bit shift to the right, when there are no bits left the value is 0, so the loop ends */
			i >>= 1;
		}
		if (!i) break;
	}
	return binstr;
}

//============================================================================================================================
//  Convert bit string to long integer.
//============================================================================================================================
long bin2dec(String s) {
	long l = 0;
	// Pull most sig bits from left of bit string, since they will get shifted up in degree
	for (int j = 0; j < s.GetLength(); j++) {
		if (s[j] != '1' && s[j] != '0') {
			Exclamation(CAT << "Invalid bit string in bin2dec: Must be 1 or 0 " << s);
		}
		l|= (s[j] == '1')? 1 :0;
		l<<= 1; // Save added bit and make room for next bit
	}
	return l;
}

#endif
